home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
221_01
/
cc21.c
< prev
next >
Wrap
Text File
|
1980-01-01
|
13KB
|
504 lines
/* >>>>>> start of cc2 <<<<<<<< */
/* */
/* Get required array size */
/* */
/* invoked when declared variable is followed by "[" */
/* this routine makes subscript the absolute */
/* size of the array. */
needsub()
{
int num[1];
if(match("]"))return (0); /* null size */
if (number(num)==0) /* go after a number */
{errrpt("must be constant"); /* it isn't */
num[0]=1; /* so force one */
}
if (num[0]<0)
{errrpt("negative size illegal");
num[0]=(-num[0]);
}
needbrack("]"); /* force single dimension */
return (num[0]); /* and return size */
}
/* */
/* Begin a function */
/* */
/* Called from "parse" this routine tries to make a function */
/* out of what follows. */
newfunc(class) int class; {
/* next lines added by dieter flunkert 23 jan 1986 */
int argtop; /* top of argument stack */
char n[namesize],*ptr;
#ifdef STGOTO
nogo=noloc=0;
#endif
#ifdef PHASE2
if(monitor) {cout('\n',stderr);sout(line,stderr);}
#endif
if (symname(n)==0)
{errrpt("illegal function or declaration");
kill(); /* invalidate line */
return;
}
if(ptr=findglb(n)) /* already in symbol table ? */
{if(ptr[ident]!=function)multidef(n);
/* already variable by that name */
else if(ptr[offset]==function)multidef(n);
/* already function by that name */
else ptr[offset]=function;
/* otherwise we have what was earlier*/
/* assumed to be a function */
}
/* if not in table, define as a function now */
else addglb(n,function,cint,function);
/* we had better see open paren for args... */
if(match("(")==0)errrpt("missing open paren");
/* next lines added by dieter flunkert 23 jan 1986 */
if(first_func) {
defname(n); /* define name of asm module */
first_func = 0;
}
entry(n, class);
if(DEFDEBUG) debug(n);
/* ** Clear local stack pointer rev. 1P */
locptr = startloc; /* ** 2 lines inserted rev. 1P */
argstk=0; /* init arg count */
while(match(")")==0) /* then count args */
/* any legal name bumps arg count */
{if(symname(n)) /* **+ Modification rev. 1P */
{ if (findloc(n)) multidef(n);
else { addloc(n, 0, 0, argstk);
argstk = argstk + 2;
}
} /* **- End of modification rev. 1P */
else{errrpt("illegal argument name");junk();}
blanks();
/* if not closing paren, should be comma */
if(streq(line+lptr,")")==0)
{if(match(",")==0)
errrpt("expected comma");
}
if(endst())break;
}
/* ** Next line deleted rev. 1P */
/* ** locptr=startloc; ** */ /* "clear" local symbol table*/
stkp=0; /* preset stack ptr */
/* next line added by dieter flunkert 23 jan 1986 */
argtop=argstk; /* save top of argument stack */
while(argstk)
/* now let user declare what types of things */
/* those arguments were */
{if(amatch("char",4)){getarg(argtop,cchar);ns();}
else if(amatch("int",3)){getarg(argtop,cint);ns();}
else{errrpt("wrong number args");break;}
}
if(statement()!=streturn) /* do a statement, but if */
/* it's a return, skip */
/* cleaning up the stack */
{modstk(0);
ret();
}
stkp=0; /* reset stack ptr again */
locptr=startloc; /* deallocate all locals */
if(litptr) { /* dump literal pool */
printlabel(litlab);
dumplits(1);
litlab=getlabel();
}
}
/* */
/* Declare argument types */
/* */
/* called from "newfunc" this routine adds an entry in the */
/* local symbol table for each named argument */
/* ** Function completely rewritten rev. 1P */
/* modified by dieter flunkert 23 jan 1986 */
/* argtop is not allowed to change value. This was the case
if a function had a declaration like:
int i; char c; */
getarg(argtop,t) /* t = cchar or cint */
int argtop,t;
{
int j, legalname, address;
char n[namesize], c, *argptr;
/* next line deleted by dieter flunkert 23 jan 1986 */
/* argtop = argstk; */
while(1)
{if(argstk==0)return; /* no more args */
if(match("*"))j=pointer;
else j=variable;
if((legalname = symname(n)) == 0) illname();
if(match("[")) /* pointer ? */
/* it is a pointer, so skip all */
/* stuff between "[]" */
{while(inbyte()!=']')
if(endst())break;
j=pointer;
/* add entry as pointer */
}
if (legalname) {
if (argptr = findloc(n)) {
/* Add in details of the type and address of */
/* the name */
argptr[ident] = j;
argptr[type] = t;
address = argtop - (argptr[offset] + (argptr[offset+1]<<8));
putint(address, argptr+offset, offsize);
}
else errrpt("Expected argument name");
}
argstk=argstk-2; /* cnt down */
if (endst()) return;
if (match(",") == 0) errrpt("expected comma");
}
}
/* ** End of modifications rev. 1P */
/*
** statement parser
**
** called whenever syntax requires a statement
** this routine performs that statement
** and returns a number telling which one
*/
statement() {
int class;
if ((ch==0) && (eof)) return;
if(amatch("static",6)) {
class=statik;
if(++stdecl == 1) /* there are static variables */
jump(stlab=getlabel()); /* skip static declarations */
}
else class=stkloc;
if(amatch("char",4)) {declloc(cchar,class);ns();}
else if(amatch("int",3)) {declloc(cint,class);ns();}
else {
if(stdecl > 0) {
postlabel(stlab);
stdecl = 0;
}
if(declared >= 0) {
#ifdef STGOTO
if(ncmp > 1) nogo=declared; /* disable goto if any */
#endif
stkp=modstk(stkp - declared);
declared = -1;
}
if(match("{")) compound();
else if(amatch("if",2)) {doif();lastst=stif;}
else if(amatch("while",5)) {dowhile();lastst=stwhile;}
#ifdef STDO
else if(amatch("do",2)) {dodo();lastst=STDO;}
#endif
#ifdef STFOR
else if(amatch("for",3)) {dofor();lastst=STFOR;}
#endif
#ifdef STSWITCH
else if(amatch("switch",6)) {doswitch();lastst=STSWITCH;}
else if(amatch("case",4)) {docase();lastst=STCASE;}
else if(amatch("default",7)) {dodefault();lastst=STDEF;}
#endif
#ifdef STGOTO
else if(amatch("goto", 4)) {dogoto(); lastst=STGOTO;}
else if(dolabel()) lastst=STLABEL;
#endif
else if(amatch("return",6)) {doreturn();ns();lastst=streturn;}
else if(amatch("break",5)) {dobreak();ns();lastst=stbreak;}
else if(amatch("continue",8)){docont();ns();lastst=stcont;}
else if(match(";")) ;
else if(match("#asm")) {doasm();lastst=stasm;}
else {doexpression();ns();lastst=stexp;}
}
return lastst;
}
#ifdef STDO
dodo() {
int wq[4], top;
addwhile(wq);
postlabel(top=getlabel());
statement();
needbrack("while");
postlabel(wq[wqloop]);
test(wq[wqlab],YES);
jump(top);
postlabel(wq[wqlab]);
delwhile();
ns();
}
#endif
#ifdef STFOR
dofor() {
int wq[4], lab1, lab2;
addwhile(wq);
lab1=getlabel();
lab2=getlabel();
needbrack("(");
if(match(";")==0) {
doexpression(); /* expr 1 */
ns();
}
postlabel(lab1);
if(match(";")==0) {
test(wq[wqlab],NO); /* expr 2 */
ns();
}
jump(lab2);
postlabel(wq[wqloop]);
if(match(")")==0) {
doexpression(); /* expr 3 */
needbrack(")");
}
jump(lab1);
postlabel(lab2);
statement();
jump(wq[wqloop]);
postlabel(wq[wqlab]);
delwhile();
}
#endif
#ifdef STSWITCH
doswitch() {
int wq[4], endlab, swact, swdef, *swnex, *swptr;
swact=swactive;
swdef=swdefault;
swnex=swptr=swnext;
addwhile(wq);
needbrack("(");
doexpression(); /* evaluate switch expression */
needbrack(")");
swdefault=0;
swactive=1;
jump(endlab=getlabel());
statement(); /* cases, etc. */
jump(wq[wqlab]);
postlabel(endlab);
sw(); /* match cases */
while(swptr < swnext) {
defstorage(cint>>2);
printlabel(*swptr++); /* case label */
outbyte(',');
outdec(*swptr++); /* case value */
nl();
}
defstorage(cint>>2);
outdec(0);
nl();
if(swdefault) jump(swdefault);
postlabel(wq[wqlab]);
delwhile();